home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / bbs_util / bsrc_260.zip / SRC.ZIP / YOOHOO.C < prev    next >
C/C++ Source or Header  |  1996-02-20  |  36KB  |  1,147 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*              (C) Copyright 1987-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*               This module was written by Vince Perriello                 */
  13. /*                                                                          */
  14. /*                     BinkleyTerm "YooHoo" Processor                       */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. /* Include this file before any other includes or defines! */
  45.  
  46. #include "includes.h"
  47.  
  48. int Send_Hello_Packet (int);
  49. int Recv_Hello_Packet (int);
  50.  
  51. /*
  52.  * Data structure used by all YooHoo state machine functions.
  53.  * Contains all data which needs to be passed between various states.
  54.  *
  55.  */
  56.  
  57. typedef struct
  58. {
  59.     long control;                /* Must always start with a long!   */
  60.     long timer1;                /* Outermost timer                  */
  61.     long timer2;                /* Next inner timer                 */
  62.     long timer3;                /* Next inner timer                 */
  63.     struct _Hello Hello;        /* Data packet                      */
  64.     word crc;                    /* CRC of data packet               */
  65.     word hiscrc;                /* other's CRC of data packet       */
  66.     int sender;                    /* Set to 1 if we're calling him    */
  67.     int result;                    /* Result we want to send out       */
  68.     int retries;                /* Number of retries                */
  69.     int count;                    /* Number of characters received    */
  70. } YHARGS, *YHARGSP;
  71.  
  72. int YRInit (YHARGSP);            /* Called by state machine at start */
  73. int YRExit (YHARGSP);            /* Called by state machine at end   */
  74. int YRGetHello (YHARGSP);        /* YR1 state processing function    */
  75. int YRWaitResp (YHARGSP);        /* YR2 state processing function    */
  76. int YRPollPeer (YHARGSP);        /* YR3 state processing function    */
  77. int YRSndHello (YHARGSP);        /* YR4 state processing function    */
  78.  
  79. int YSInit (YHARGSP);            /* Called by state machine at start */
  80. int YSExit (YHARGSP);            /* Called by state machine at end   */
  81. int YSSndHello (YHARGSP);        /* YS1 state processing function    */
  82. int YSWaitResp (YHARGSP);        /* YS2 state processing function    */
  83. int YSGetHello (YHARGSP);        /* YS3 state processing function    */
  84.  
  85. int SHInit (YHARGSP);            /* Called by state machine at start */
  86. int SHExit (YHARGSP);            /* Called by state machine at end   */
  87. int SHInitSend (YHARGSP);        /* SH1 state processing function    */
  88. int SHSendHedr (YHARGSP);        /* SH2 state processing function    */
  89. int SHSendCRC (YHARGSP);        /* SH3 state processing function    */
  90. int SHGetResp (YHARGSP);        /* SH4 state processing function    */
  91. int SHBumpCnt (YHARGSP);        /* SH5 state processing function    */
  92.  
  93. int RHInit (YHARGSP);            /* Called by state machine at start */
  94. int RHExit (YHARGSP);            /* Called by state machine at end   */
  95. int RHSendENQ (YHARGSP);        /* RH1 state processing function    */
  96. int RHWaitHedr (YHARGSP);        /* RH2 state processing function    */
  97. int RHTossJunk (YHARGSP);        /* RH3 state processing function    */
  98. int RHReSynch (YHARGSP);        /* RH4 state processing function    */
  99. int RHHdrSetup (YHARGSP);        /* RH5 state processing function    */
  100. int RHGetHChar (YHARGSP);        /* RH6 state processing function    */
  101. int RHStoHChar (YHARGSP);        /* RH7 state processing function    */
  102. int RHCheckCRC (YHARGSP);        /* RH8 state processing function    */
  103. int RHCountERR (YHARGSP);        /* RH9 state processing function    */
  104. int RHHelloOK (YHARGSP);        /* RH10 state processing function   */
  105.  
  106. #define YR0    0                /* Reserved value of 0 for init     */
  107. #define YRexit 0                /* Slot 1 is exit, but called by 0  */
  108. #define YR1    2                /* First "user" slot is 2.          */
  109. #define YR2    3                /* After that, it all maps n : n+1  */
  110. #define YR3    4
  111. #define YR4    5
  112.  
  113. #define YS0    0                /* Reserved value of 0 for init     */
  114. #define YSexit 0                /* Slot 1 is exit, but called by 0  */
  115. #define YS1    2                /* First "user" slot is 2.          */
  116. #define YS2    3                /* After that, it all maps n : n+1  */
  117. #define YS3    4
  118.  
  119. #define SH0    0                /* Reserved value of 0 for init     */
  120. #define SHexit 0                /* Slot 1 is exit, but called by 0  */
  121. #define SH1    2                /* First "user" slot is 2.          */
  122. #define SH2    3                /* After that, it all maps n : n+1  */
  123. #define SH3    4
  124. #define SH4    5
  125. #define SH5    6
  126.  
  127. #define RH0    0                /* Reserved value of 0 for init     */
  128. #define RHexit 0                /* Slot 1 is exit, but called by 0  */
  129. #define RH1    2                /* First "user" slot is 2.          */
  130. #define RH2    3                /* After that, it all maps n : n+1  */
  131. #define RH3    4
  132. #define RH4    5
  133. #define RH5    6
  134. #define RH6    7
  135. #define RH7    8
  136. #define RH8    9
  137. #define RH9    10
  138. #define RH10   11
  139.  
  140. typedef struct
  141. {
  142.     char *state_name;
  143.     int (*state_func) (YHARGSP);
  144. } YSTATES, *YSTATEP;
  145.  
  146. YSTATES YooHoo_Rcvr[] =
  147. {                                /* Table used by state machine      */
  148.     {"YRInit", YRInit},            /* And referred to by 'YRn' defines */
  149.     {"YRExit", YRExit},            /* listed above ...                 */
  150.     {"YRGetHello", YRGetHello},
  151.     {"YRWaitResp", YRWaitResp},
  152.     {"YRPollPeer", YRPollPeer},
  153.     {"YRSndHello", YRSndHello},
  154. };
  155.  
  156. YSTATES YooHoo_Sndr[] =
  157. {                                /* Table used by state machine      */
  158.     {"YSInit", YSInit},            /* And referred to by 'YRn' defines */
  159.     {"YSExit", YSExit},            /* listed above ...                 */
  160.     {"YSSndHello", YSSndHello},
  161.     {"YSWaitResp", YSWaitResp},
  162.     {"YSGetHello", YSGetHello},
  163. };
  164.  
  165. YSTATES Snd_Hello[] =
  166. {                                /* Table used by state machine      */
  167.     {"SHInit", SHInit},            /* And referred to by 'SHn' defines */
  168.     {"SHExit", SHExit},            /* listed above ...                 */
  169.     {"SHInitSend", SHInitSend},
  170.     {"SHSendHedr", SHSendHedr},
  171.     {"SHSendCRC", SHSendCRC},
  172.     {"SHGetResp", SHGetResp},
  173.     {"SHBumpCnt", SHBumpCnt},
  174. };
  175.  
  176. YSTATES Rcv_Hello[] =
  177. {                                /* Table used by state machine      */
  178.     {"RHInit", RHInit},            /* And referred to by 'RHn' defines */
  179.     {"RHExit", RHExit},            /* listed above ...                 */
  180.     {"RHSendENQ", RHSendENQ},
  181.     {"RHWaitHedr", RHWaitHedr},
  182.     {"RHTossJunk", RHTossJunk},
  183.     {"RHReSynch", RHReSynch},
  184.     {"RHHdrSetup", RHHdrSetup},
  185.     {"RHGetHChar", RHGetHChar},
  186.     {"RHStoHChar", RHStoHChar},
  187.     {"RHCheckCRC", RHCheckCRC},
  188.     {"RHCountERR", RHCountERR},
  189.     {"RHHelloOK", RHHelloOK},
  190. };
  191.  
  192. /*--------------------------------------------------------------------------*/
  193. /* YOOHOO SENDER    (used when I am the CALLING system)                     */
  194. /*--------------------------------------------------------------------------*/
  195. int 
  196. YooHoo_Sender (void)
  197. {
  198.     YHARGS args;
  199.     int res;
  200.  
  201.     args.result = 0;
  202.  
  203.     res = state_machine ((STATEP) YooHoo_Sndr, &args, 2);
  204.     return (res);
  205. }
  206.  
  207. int 
  208. YSInit (YHARGSP args)
  209. {
  210.  
  211.     if (un_attended && fullscreen)
  212.     {
  213.         sb_move (filewin, 2, 2);
  214.         sb_puts (filewin, "YooHoo");
  215.         sb_show ();
  216.     }
  217.     else
  218.     {
  219.         set_xy ("YooHoo ");
  220.     }
  221.  
  222.     /*--------------------------------------------------------------------*/
  223.     /* Clean up any mess that may be around                               */
  224.     /*--------------------------------------------------------------------*/
  225.  
  226.     CLEAR_OUTBOUND ();
  227.     CLEAR_INBOUND ();
  228.     XON_DISABLE ();
  229.  
  230.     happy_compiler = args->result;
  231.  
  232.     return (YS1);
  233. }
  234.  
  235. /*
  236.  * This routine is called by the state machine when the '??exit'
  237.  * state is seen. Its return value is what the state machine
  238.  * will return to its caller as the result of the function.
  239.  *
  240.  */
  241.  
  242. int 
  243. YSExit (YHARGSP args)
  244. {
  245.     return (args->result);
  246. }
  247.  
  248. /*
  249.  .-----+----------+-------------------------+-------------------------+-----.
  250.  | YS1 | SndHello | Successful              | Looks like WaZOO        | YS2 |
  251.  |     | (state   +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  252.  |     |  SH1)    | Not successful          | Repeat whole thing      | exit|
  253.  `-----+----------+-------------------------+-------------------------+-----'
  254. */
  255. int 
  256. YSSndHello (YHARGSP args)
  257. {
  258.     if (!Send_Hello_Packet (1))
  259.     {
  260.         status_line (MSG_TXT (M_HE_HUNG_UP));
  261.         return (YSexit);
  262.     }
  263.  
  264.     happy_compiler = args->result;
  265.     return (YS2);
  266. }
  267.  
  268. /*
  269.  .-----+----------+-------------------------+-------------------------+-----.
  270.  | YS2 | WaitResp | 30 sec timer expires    | repeat whole thing      | exit|
  271.  |     |          | or lost carrier         |                         |     |
  272.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  273.  |     |          | Received YOOHOO         | Another WaZOO, go       | YS3 |
  274.  |     |          |                         | process receive         |     |
  275.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  276.  |     |          | Received debris         | Repeat whole thing      | YS2 |
  277.  `-----+----------+-------------------------+-------------------------+-----'
  278. */
  279. int 
  280. YSWaitResp (YHARGSP args)
  281. {
  282.     long resp_timer = timerset (3000);
  283.  
  284.     while (TIMED_READ (5) != YOOHOO)
  285.     {
  286.         if (timeup (resp_timer))
  287.         {
  288.             status_line ("!No YOOHOO/2U2");
  289.             status_line (IDUNNO_msg);
  290.             return (YSexit);
  291.         }
  292.     }
  293.  
  294.     happy_compiler = args->result;
  295.     return (YS3);
  296. }
  297.  
  298. /*
  299.  .-----+----------+-------------------------+-------------------------+-----.
  300.  | YS3 | GetHello | Information             | Report Success          | exit|
  301.  |     | (state   | Successfully            |                         |     |
  302.  |     |  RH1)    | Exchanged               |                         |     |
  303.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  304.  |     |          | Failure                 | Repeat whole thing      | exit|
  305.  `-----+----------+-------------------------+-------------------------+-----'
  306. */
  307. int 
  308. YSGetHello (YHARGSP args)
  309. {
  310.     args->result = Recv_Hello_Packet (1);
  311.     return (YSexit);
  312. }
  313.  
  314. /*--------------------------------------------------------------------------*/
  315. /* YOOHOO RECEIVER  (Used when I am the CALLED system)                      */
  316. /*--------------------------------------------------------------------------*/
  317.  
  318. int 
  319. YooHoo_Receiver (void)
  320. {
  321.     YHARGS args;
  322.     int res;
  323.  
  324.     args.result = 0;
  325.  
  326.     res = state_machine ((STATEP) YooHoo_Rcvr, &args, 2);
  327.     return (res);
  328. }
  329.  
  330. int 
  331. YRInit (YHARGSP args)
  332. {
  333.  
  334.     if (un_attended && fullscreen)
  335.     {
  336.         sb_move (filewin, 2, 2);
  337.         sb_puts (filewin, "YooHoo");
  338.         sb_show ();
  339.     }
  340.     else
  341.     {
  342.         set_xy ("YooHoo ");
  343.     }
  344.  
  345.     /*--------------------------------------------------------------------*/
  346.     /* Clean up any mess that may be around                               */
  347.     /*--------------------------------------------------------------------*/
  348.  
  349.     CLEAR_OUTBOUND ();
  350.     CLEAR_INBOUND ();
  351.     XON_DISABLE ();
  352.  
  353.     happy_compiler = args->result;
  354.  
  355.     return (YR1);
  356. }
  357.  
  358. /*
  359.  * This routine is called by the state machine when the '??exit'
  360.  * state is seen. Its return value is what the state machine
  361.  * will return to its caller as the result of the function.
  362.  *
  363.  */
  364.  
  365. int 
  366. YRExit (YHARGSP args)
  367. {
  368.     return (args->result);
  369. }
  370.  
  371. /*
  372.  .-----+----------+-------------------------+-------------------------+-----.
  373.  | YR1 | GetHello | Information             | Start 20 sec timer      | YR2 |
  374.  |     | (state   | Successfully            | Initialize retry count  |     |
  375.  |     |  RH1)    | Exchanged               | Send YooHoo             |     |
  376.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  377.  |     |          | Failure                 | Repeat whole thing      | exit|
  378.  `-----+----------+-------------------------+-------------------------+-----'
  379. */
  380. int 
  381. YRGetHello (YHARGSP args)
  382. {
  383.     if (Recv_Hello_Packet (0) == 0)
  384.         return (YRexit);
  385.     args->timer1 = timerset (2000);
  386.     args->retries = 0;
  387.     SENDBYTE (YOOHOO);
  388.     return (YR2);
  389. }
  390.  
  391. /*
  392.  .-----+----------+-------------------------+-------------------------+-----.
  393.  | YR2 | WaitResp | 20 sec timeout          | try again               | YR3 |
  394.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  395.  |     |          | Lost carrier            | Failure                 | exit|
  396.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  397.  |     |          | Received ENQ            | Go send hello           | YR4 |
  398.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  399.  |     |          | Received debris         | Keep looking            | YR2 |
  400.  `-----+----------+-------------------------+-------------------------+-----'
  401. */
  402. int 
  403. YRWaitResp (YHARGSP args)
  404. {
  405.     while (TIMED_READ (5) != ENQ)
  406.     {
  407.         if (!CARRIER)
  408.         {
  409.             status_line (MSG_TXT (M_NO_CARRIER));
  410.             return (YRexit);
  411.         }
  412.         if (timeup (args->timer1))
  413.             return (YR3);
  414.     }
  415.     return (YR4);
  416. }
  417.  
  418. /*
  419.  .-----+----------+-------------------------+-------------------------+-----.
  420.  | YR3 | PollPeer | More than 3 retries     | Give it up              | exit|
  421.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  422.  |     |          | Less than 3 retries     | Bump retry count        | YR2 |
  423.  |     |          |                         | Clear input buffer      |     |
  424.  |     |          |                         | Send YOOHOO             |     |
  425.  |     |          |                         | Restart 20 sec timer    |     |
  426.  `-----+----------+-------------------------+-------------------------+-----'
  427. */
  428. int 
  429. YRPollPeer (YHARGSP args)
  430. {
  431.     if (++(args->retries) > 3)
  432.     {
  433.         status_line (MSG_TXT (M_FUBAR_MSG));
  434.         b_init ();
  435.         return (YRexit);
  436.     }
  437.  
  438.     CLEAR_INBOUND ();
  439.     SENDBYTE (YOOHOO);
  440.     args->timer1 = timerset (2000);
  441.     return (YR2);
  442. }
  443.  
  444. /*
  445.  .-----+----------+-------------------------+-------------------------+-----.
  446.  | YR4 | SndHello | Successful              | All done, report success| exit|
  447.  |     | (state   +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  448.  |     |  SH1)    | Not successful          | Repeat whole thing      | exit|
  449.  `-----+----------+-------------------------+-------------------------+-----'
  450. */
  451. int 
  452. YRSndHello (YHARGSP args)
  453. {
  454.     if ((args->result = Send_Hello_Packet (0)) == 0)
  455.         b_init ();
  456.     return (YRexit);
  457. }
  458.  
  459. /*--------------------------------------------------------------------------*/
  460. /* SEND HELLO PACKET                                                        */
  461. /*--------------------------------------------------------------------------*/
  462. int 
  463. Send_Hello_Packet (int Sender)
  464. {
  465.     YHARGS args;
  466.     int res;
  467.  
  468.     args.result = 0;
  469.     args.sender = Sender;
  470.  
  471.     (void) n_getpassword (&remote_addr);    /* Update "assumed" */
  472.  
  473.     res = state_machine ((STATEP) Snd_Hello, &args, 2);
  474.     return (res);
  475. }
  476.  
  477. int 
  478. SHInit (YHARGSP args)
  479. {
  480.     happy_compiler = args->result;
  481.  
  482.     return (SH1);
  483. }
  484.  
  485. /*
  486.  * This routine is called by the state machine when the '??exit'
  487.  * state is seen. Its return value is what the state machine
  488.  * will return to its caller as the result of the function.
  489.  *
  490.  */
  491.  
  492. int 
  493. SHExit (YHARGSP args)
  494. {
  495.     return (args->result);
  496. }
  497.  
  498. /*
  499.  .-----+----------+-------------------------+-------------------------+-----.
  500.  | SH1 | InitSend |                         | Disable XON/XOFF        | SH2 |
  501.  |     |          |                         | Set retry count to 0    |     |
  502.  `-----+----------+-------------------------+-------------------------+-----'
  503. */
  504. int 
  505. SHInitSend (YHARGSP args)
  506. {
  507.  
  508.     XON_DISABLE ();
  509.     args->retries = 0;
  510.  
  511.     return (SH2);
  512. }
  513.  
  514. /*
  515.  .-----+----------+-------------------------+-------------------------+-----.
  516.  | SH2 | SendHedr |                         | Send Hex 1f, then       | SH3 |
  517.  |     |          |                         | Send HELLO struct       |     |
  518.  `-----+----------+-------------------------+-------------------------+-----'
  519. */
  520. int 
  521. SHSendHedr (YHARGSP args)
  522. {
  523.     word can_do_domain = 0;
  524.     word crc;
  525.     char *sptr;
  526.     int i;
  527.  
  528.     /*--------------------------------------------------------------------*/
  529.     /* Setup HELLO structure                                              */
  530.     /*--------------------------------------------------------------------*/
  531.  
  532.     (void) memset ((char *) &args->Hello, 0, sizeof (struct _Hello));
  533.  
  534.     args->Hello.signal = 'o';
  535.     args->Hello.hello_version = 1;
  536.  
  537.     args->Hello.product = PRDCT_CODE;
  538.     args->Hello.product_maj = (word) BINK_MAJVERSION;
  539.     args->Hello.product_min = (word) BINK_MINVERSION;
  540.  
  541.     (void) strncpy (args->Hello.sysop, sysop, 19);
  542.     args->Hello.sysop[19] = '\0';
  543.  
  544.     args->Hello.my_zone = alias[assumed].Zone;
  545.     if ((pvtnet >= 0) && (args->sender) &&
  546.         ((called_addr.Zone == boss_addr.Zone) || (called_addr.Zone == 0) || (boss_addr.Zone == 0)) &&
  547.         (called_addr.Net == boss_addr.Net) && (called_addr.Node == boss_addr.Node) &&
  548.         ((called_addr.Domain == boss_addr.Domain) || (boss_addr.Domain == NULL) || (called_addr.Domain == NULL)))
  549.     {
  550.         args->Hello.my_net = boss_addr.Net;
  551.         args->Hello.my_node = boss_addr.Node;
  552.         args->Hello.my_point = alias[assumed].Node;
  553.     }
  554.     else
  555.     {
  556.         args->Hello.my_net = alias[assumed].Net;
  557.         args->Hello.my_node = alias[assumed].Node;
  558.         args->Hello.my_point = alias[assumed].Point;
  559.     }
  560.  
  561. /*
  562.  * If we are the calling system, turn on all our capabilities.
  563.  * If we are the called system, choose from the set that the
  564.  * caller gave us, and only send the one we prefer.
  565.  */
  566.     can_do_domain = (my_addr.Domain != NULL) ? DO_DOMAIN : 0;
  567.     if (args->sender == 0)
  568.     {
  569.         can_do_domain = remote_capabilities & can_do_domain;
  570.         if (remote_capabilities & my_capabilities & DOES_IANUS)
  571.             args->Hello.capabilities = DOES_IANUS;
  572.         else if (remote_capabilities & my_capabilities & DOES_HYDRA)
  573.             args->Hello.capabilities = DOES_HYDRA;
  574.         else if (remote_capabilities & my_capabilities & ZED_ZAPPER)
  575.             args->Hello.capabilities = ZED_ZAPPER;
  576.         else if (remote_capabilities & my_capabilities & ZED_ZIPPER)
  577.             args->Hello.capabilities = ZED_ZIPPER;
  578.         else if (remote_capabilities & my_capabilities & Y_DIETIFNA)
  579.             args->Hello.capabilities = Y_DIETIFNA;
  580.     }
  581.     else
  582.         args->Hello.capabilities = my_capabilities;
  583.  
  584.     (void) strncpy (args->Hello.my_name, system_name, 58);
  585.     args->Hello.my_name[58] = '\0';
  586.     args->Hello.capabilities |= can_do_domain;
  587.     if (can_do_domain && (alias[assumed].Domain != NULL))
  588.     {
  589.         if (strlen (system_name) + strlen (alias[assumed].Domain) > 57)
  590.         {
  591.             args->Hello.my_name[57 - strlen (alias[assumed].Domain)] = '\0';
  592.         }
  593.         sptr = args->Hello.my_name + strlen (args->Hello.my_name) + 1;
  594.         (void) strcpy (sptr, alias[assumed].Domain);
  595.     }
  596.  
  597.     if (n_getpassword (&remote_addr) > 0)
  598.     {
  599.         (void) strncpy ((char *) (args->Hello.my_password), remote_password, 8);
  600.     }
  601.  
  602.     if ((matrix_mask & TAKE_REQ) &&
  603.         ((args->sender == 0) || (on_our_nickel)))
  604.         args->Hello.capabilities |= WZ_FREQ;
  605.     remote_pickup = 1;
  606.  
  607.     /*--------------------------------------------------------------------*/
  608.     /* Send the packet.                                                   */
  609.     /* Load outbound buffer quickly, and get modem busy sending.          */
  610.     /*--------------------------------------------------------------------*/
  611.  
  612.     SENDBYTE (0x1f);
  613.     sptr = (char *) (&args->Hello);
  614.     SENDCHARS (sptr, 128, 1);
  615.  
  616.     /*--------------------------------------------------------------------*/
  617.     /* Calculate CRC while modem is sending its buffer                    */
  618.     /*--------------------------------------------------------------------*/
  619.  
  620.     for (crc = 0, i = 0; i < 128; i++)
  621.     {
  622.         crc = xcrc (crc, (byte) sptr[i]);
  623.     }
  624.  
  625.     args->crc = crc;
  626.     return (SH3);
  627. }
  628.  
  629. /*
  630.  .-----+----------+-------------------------+-------------------------+-----.
  631.  | SH3 | SendCRC  |                         | Clear Input Buffer      | SH4 |
  632.  |     |          |                         | Send two-byte CRC of pkt|     |
  633.  |     |          |                         | MSB followed by LSB     |     |
  634.  |     |          |                         | Start 40 second timer   |     |
  635.  `-----+----------+-------------------------+-------------------------+-----'
  636. */
  637. SHSendCRC (YHARGSP args)
  638. {
  639.     CLEAR_INBOUND ();
  640.  
  641.     SENDBYTE ((unsigned char) (args->crc >> 8));
  642.     SENDBYTE ((unsigned char) (args->crc & 0xff));
  643.  
  644.     args->timer1 = timerset (4000);
  645.     return (SH4);
  646. }
  647.  
  648. /*
  649.  .-----+----------+-------------------------+-------------------------+-----.
  650.  | SH4 | GetResp  | 40 second timer expires | Failed to send packet   | exit|
  651.  |     |          | or carrier lost         |                         |     |
  652.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  653.  |     |          | ACK received            | Successful transmission | exit|
  654.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  655.  |     |          | '?' received            | Error, bump retry count | SH5 |
  656.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  657.  |     |          | ENQ received            | Out of sync, retry      | SH5 |
  658.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  659.  |     |          | other character recvd   | Debris, keep watching   | SH4 |
  660.  `-----+----------+-------------------------+-------------------------+-----'
  661. */
  662. SHGetResp (YHARGSP args)
  663. {
  664.     int i;
  665.     char junkbuff[80];
  666.  
  667.     while ((i = TIMED_READ (5)) != ACK)
  668.     {
  669.         if (timeup (args->timer1))
  670.         {
  671.             (void) sprintf (junkbuff, "!%s", MSG_TXT (M_TIMEOUT));
  672.             status_line (junkbuff);
  673.             return (SHexit);
  674.         }
  675.  
  676.         if (!CARRIER)
  677.         {
  678.             status_line (MSG_TXT (M_NO_CARRIER));
  679.             return (SHexit);
  680.         }
  681.  
  682.         if (got_ESC ())
  683.         {
  684.             LOWER_DTR ();
  685.             status_line (MSG_TXT (M_KBD_MSG));
  686.             return (SHexit);
  687.         }
  688.  
  689.         switch (i)
  690.         {
  691.         case '?':
  692.             status_line (MSG_TXT (M_DRATS));
  693.  
  694.             /* Fall through into ENQ case */
  695.  
  696.         case ENQ:
  697.             return (SH5);
  698.  
  699.         default:
  700.             break;
  701.         }
  702.     }
  703.  
  704.     args->result = 1;
  705.     return (SHexit);
  706. }
  707.  
  708. /*
  709.  .-----+----------+-------------------------+-------------------------+-----.
  710.  | SH5 | BumpCnt  | Retry count >= 10       | Failed to send packet   | exit|
  711.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  712.  |     |          | Count < 10              | Clear inbound buffer    | SH2 |
  713.  `-----+----------+-------------------------+-------------------------+-----'
  714. */
  715.  
  716. SHBumpCnt (YHARGSP args)
  717. {
  718.     if (++(args->retries) >= 10)
  719.     {
  720.         status_line (MSG_TXT (M_FUBAR_MSG));
  721.         return (SHexit);
  722.     }
  723.     CLEAR_INBOUND ();
  724.     return (SH2);
  725. }
  726.  
  727. /*--------------------------------------------------------------------------*/
  728. /* RECEIVE HELLO PACKET                                                     */
  729. /*--------------------------------------------------------------------------*/
  730. int 
  731. Recv_Hello_Packet (int Sender)
  732. {
  733.     YHARGS args;
  734.     int res;
  735.  
  736.     args.result = 0;
  737.     args.sender = Sender;
  738.  
  739.     res = state_machine ((STATEP) Rcv_Hello, &args, 2);
  740.     return (res);
  741. }
  742.  
  743. int 
  744. RHInit (YHARGSP args)
  745. {
  746.     happy_compiler = args->result;
  747.  
  748.     return (RH1);
  749. }
  750.  
  751. /*
  752.  * This routine is called by the state machine when the '??exit'
  753.  * state is seen. Its return value is what the state machine
  754.  * will return to its caller as the result of the function.
  755.  *
  756.  */
  757.  
  758. int 
  759. RHExit (YHARGSP args)
  760. {
  761.     if (args->result == 0)
  762.         b_init ();
  763.     return (args->result);
  764. }
  765.  
  766. /*
  767.  .-----+----------+-------------------------+-------------------------+-----.
  768.  | RH1 | SendENQ  |                         | Start 2 minute timer    | RH2 |
  769.  |     |          |                         | Send an ENQ character   |     |
  770.  `-----+----------+-------------------------+-------------------------+-----'
  771. */
  772. int 
  773. RHSendENQ (YHARGSP args)
  774. {
  775.     if (un_attended && fullscreen)
  776.     {
  777.         sb_move (filewin, 2, 2);
  778.         sb_puts (filewin, "YooHoo/2U2");
  779.         sb_show ();
  780.     }
  781.     else
  782.     {
  783.         set_xy ("YooHoo/2U2 ");
  784.     }
  785.  
  786.     SENDBYTE (ENQ);                /* Let the other system know
  787.                                                   * we heard YooHoo. */
  788.  
  789.     args->timer1 = timerset (12000);    /* No more than 2 mins! */
  790.     args->timer2 = 0L;
  791.     args->retries = 0;
  792.     return (RH2);
  793. }
  794.  
  795. /*
  796.  .-----+----------+-------------------------+-------------------------+-----.
  797.  | RH2 | WaitHedr | 2 minute timer expires  | Report failure          | exit|
  798.  |     |          | or carrier lost         |                         |     |
  799.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  800.  |     |          | Received Hex 1f         | Got header, get packet  | RH5 |
  801.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  802.  |     |          | Received other char     | Debris, throw away      | RH3 |
  803.  |     |          |                         | Start 10 sec timer      |     |
  804.  `-----+----------+-------------------------+-------------------------+-----'
  805. */
  806. int 
  807. RHWaitHedr (YHARGSP args)
  808. {
  809.     int i;
  810.     char junkbuff[80];
  811.  
  812.     while ((i = TIMED_READ (5)) != 0x1f)
  813.     {
  814.         if (!CARRIER)
  815.         {
  816.             status_line (MSG_TXT (M_NO_CARRIER));
  817.             return (RHexit);
  818.         }
  819.  
  820.         if (got_ESC ())
  821.         {
  822.             status_line (MSG_TXT (M_KBD_MSG));
  823.             return (RHexit);
  824.         }
  825.  
  826.         if (timeup (args->timer1))
  827.         {
  828.             (void) sprintf (junkbuff, "!%s", MSG_TXT (M_TIMEOUT));
  829.             status_line (junkbuff);
  830.             return (RHexit);
  831.         }
  832.  
  833.         if (i != 0xff)
  834.         {
  835.             if (args->timer2 == 0L)
  836.                 args->timer2 = timerset (1000);
  837.             return (RH3);
  838.         }
  839.     }
  840.     return (RH5);
  841. }
  842.  
  843. /*
  844.  .-----+----------+-------------------------+-------------------------+-----.
  845.  | RH3 | TossJunk | 10 sec timer expires    | Too much noise          | RH4 |
  846.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  847.  |     |          | Received Hex 1f         | Got header, get packet  | RH5 |
  848.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  849.  |     |          | Input buffer empty      | Try to resynch          | RH4 |
  850.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  851.  |     |          | Carrier lost            | Report failure          | exit|
  852.  `-----+----------+-------------------------+-------------------------+-----'
  853. */
  854. int 
  855. RHTossJunk (YHARGSP args)
  856. {
  857.     while (!timeup (args->timer2))
  858.     {
  859.         if (got_ESC ())
  860.         {
  861.             status_line (MSG_TXT (M_KBD_MSG));
  862.             return (RHexit);
  863.         }
  864.  
  865.         if (!CHAR_AVAIL ())
  866.             return (RH4);
  867.  
  868.         if (TIMED_READ (0) == 0x1f)
  869.             return (RH5);
  870.  
  871.         if (!CARRIER)
  872.         {
  873.             status_line (MSG_TXT (M_NO_CARRIER));
  874.             return (RHexit);
  875.         }
  876.     }
  877.     return (RH4);
  878. }
  879.  
  880. /*
  881.  .-----+----------+-------------------------+-------------------------+-----.
  882.  | RH4 | ReSynch  |                         | Clear input buffer      | RH2 |
  883.  |     |          |                         | Send ENQ                |     |
  884.  `-----+----------+-------------------------+-------------------------+-----'
  885. */
  886. int 
  887. RHReSynch (YHARGSP args)
  888. {
  889.     CLEAR_INBOUND ();
  890.     SENDBYTE (ENQ);
  891.     args->timer2 = 0L;
  892.     return (RH2);
  893. }
  894.  
  895. /*
  896.  .-----+----------+-------------------------+-------------------------+-----.
  897.  | RH5 | HdrSetup |                         | Initialize CRC          |     |
  898.  |     |          |                         | Set 30 second timer     | RH6 |
  899.  `-----+----------+-------------------------+-------------------------+-----'
  900. */
  901. int 
  902. RHHdrSetup (YHARGSP args)
  903. {
  904.     (void) memset ((char *) &args->Hello, 0, sizeof (struct _Hello));
  905.  
  906.     args->crc = 0;
  907.     args->count = 0;
  908.     args->timer3 = timerset (3000);
  909.     return (RH6);
  910. }
  911.  
  912. /*
  913.  .-----+----------+-------------------------+-------------------------+-----.
  914.  | RH6 | GetHChar | 30 sec timer expires or |                         |     |
  915.  |     |          | carrier lost            | Report failure          | exit|
  916.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  917.  |     |          | Character received      | Process character       | RH7 |
  918.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  919.  |     |          | 10 seconds with no char | Error, try resync       | RH9 |
  920.  `-----+----------+-------------------------+-------------------------+-----'
  921. */
  922. int 
  923. RHGetHChar (YHARGSP args)
  924. {
  925.     long localtimer;
  926.     char junkbuff[80];
  927.  
  928.     localtimer = timerset (1000);
  929.  
  930.     while (PEEKBYTE () < 0)
  931.     {
  932.         if (timeup (args->timer3))
  933.         {
  934.             (void) sprintf (junkbuff, "!%s", MSG_TXT (M_TIMEOUT));
  935.             status_line (junkbuff);
  936.             return (RHexit);
  937.         }
  938.  
  939.         if (timeup (localtimer))
  940.             return (RH9);
  941.  
  942.         if (got_ESC ())
  943.         {
  944.             status_line (MSG_TXT (M_KBD_MSG));
  945.             return (RHexit);
  946.         }
  947.  
  948.         if (!CARRIER)
  949.         {
  950.             status_line (MSG_TXT (M_NO_CARRIER));
  951.             return (RHexit);
  952.         }
  953.  
  954.         time_release ();
  955.     }
  956.     return (RH7);
  957. }
  958.  
  959. /*
  960.  .-----+----------+-------------------------+-------------------------+-----.
  961.  | RH7 | StoHChar | Buffer and CRC filled   | Compare CRC             | RH8 |
  962.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  963.  |     |          | More characters needed  | Reset 30 sec timer      | RH6 |
  964.  `-----+----------+-------------------------+-------------------------+-----'
  965. */
  966. int 
  967. RHStoHChar (YHARGSP args)
  968. {
  969.     int c;
  970.     int i;
  971.     char *sptr = (char *) &(args->Hello);
  972.  
  973.     while (PEEKBYTE () >= 0)
  974.     {
  975.         c = TIMED_READ (0);
  976.         switch (i = args->count)
  977.         {
  978.         case 128:
  979.             args->hiscrc = c << 8;
  980.             args->count++;
  981.             break;
  982.  
  983.         case 129:
  984.             args->hiscrc += c;
  985.             return (RH8);
  986.  
  987.         default:
  988.             sptr[i] = (char) c;
  989.             args->crc = xcrc (args->crc, (byte) c);
  990.             args->count++;
  991.             break;
  992.         }
  993.     }
  994.     args->timer3 = timerset (3000);
  995.     return (RH6);
  996. }
  997.  
  998. /*
  999.  .-----+----------+-------------------------+-------------------------+-----.
  1000.  | RH8 | CheckCRC | CRC matches             | Finish Receive          | RH10|
  1001.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  1002.  |     |          | CRC doesn't match       | Handle error            | RH9 |
  1003.  `-----+----------+-------------------------+-------------------------+-----'
  1004. */
  1005. int 
  1006. RHCheckCRC (YHARGSP args)
  1007. {
  1008.     char junkbuff[80];
  1009.  
  1010.     if (args->crc == args->hiscrc)
  1011.         return (RH10);
  1012.  
  1013.     (void) sprintf (junkbuff, "!%s", MSG_TXT (M_CRC_MSG));
  1014.     status_line (junkbuff);
  1015.     return (RH9);
  1016. }
  1017.  
  1018. /*
  1019.  .-----+----------+-------------------------+-------------------------+-----.
  1020.  | RH9 | CountERR | Less than 10 errors     | Send '?' (0x3f)         | RH2 |
  1021.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  1022.  |     |          | 10 errors               | Hang up, report failure | exit|
  1023.  `-----+----------+-------------------------+-------------------------+-----'
  1024. */
  1025. int 
  1026. RHCountERR (YHARGSP args)
  1027. {
  1028.     if ((args->retries++) < 10)
  1029.     {
  1030.         CLEAR_INBOUND ();
  1031.         SENDBYTE ('?');
  1032.         return (RH2);
  1033.     }
  1034.  
  1035.     status_line (MSG_TXT (M_FUBAR_MSG));
  1036.     return (RHexit);
  1037. }
  1038.  
  1039. /*
  1040.  .-----+----------+-------------------------+-------------------------+-----.
  1041.  | RH10| HelloOK  |                         | Clear inbound buffer    | exit|
  1042.  |     |          |                         | Send ACK                |     |
  1043.  `-----+----------+-------------------------+-------------------------+-----'
  1044. */
  1045. int 
  1046. RHHelloOK (YHARGSP args)
  1047. {
  1048.     char *p;
  1049.     char junkbuff[128];
  1050.     ADDR his_boss;
  1051.     int j;
  1052.     int logit = TRUE;
  1053.  
  1054.     /* The idea for removing junk characters came from Holger Schurig */
  1055.     /* Get rid of junk characters */
  1056.  
  1057.     for (p = args->Hello.my_name; *p != '\0'; p++)
  1058.         if (*p < ' ')
  1059.             *p = ' ';
  1060.  
  1061.     /* Get rid of junk characters */
  1062.  
  1063.     for (p = args->Hello.sysop; *p != '\0'; p++)
  1064.         if (*p < ' ')
  1065.             *p = ' ';
  1066.  
  1067.     remote_addr.Zone = args->Hello.my_zone;
  1068.     remote_addr.Net = args->Hello.my_net;
  1069.     remote_addr.Node = args->Hello.my_node;
  1070.     remote_addr.Point = args->Hello.my_point;
  1071.  
  1072.     if ((args->Hello.capabilities & DO_DOMAIN) && (my_addr.Domain != NULL))
  1073.     {
  1074.         remote_addr.Domain = find_domain (&(args->Hello.my_name[strlen (args->Hello.my_name) + 1]));
  1075.     }
  1076.     else
  1077.         remote_addr.Domain = NULL;
  1078.  
  1079.     if (strlen (args->Hello.my_name) > 42)
  1080.         args->Hello.my_name[42] = '\0';
  1081.  
  1082.     args->Hello.sysop[19] = '\0';
  1083.  
  1084.     remote_capabilities = args->Hello.capabilities;
  1085.  
  1086.     his_boss = remote_addr;
  1087.     his_boss.Point = 0;
  1088.  
  1089.     if (nodefind (&his_boss, 0) && !remote_addr.Zone)
  1090.         remote_addr.Zone = found_zone;
  1091.  
  1092.     (void) sprintf (junkbuff, "*%s (%s)",
  1093.         args->Hello.my_name,
  1094.         Full_Addr_Str (&remote_addr));
  1095.     status_line (junkbuff);
  1096.  
  1097.     if ((pvtnet >= 0) &&
  1098.         ((remote_addr.Zone == alias[assumed].Zone) || (remote_addr.Zone == 0)) &&
  1099.         (remote_addr.Net == boss_addr.Net) && (remote_addr.Node == boss_addr.Node) &&
  1100.         (remote_addr.Point > 0))
  1101.     {
  1102.         remote_addr.Net = pvtnet;
  1103.         remote_addr.Node = args->Hello.my_point;
  1104.         remote_addr.Point = 0;
  1105.     }
  1106.  
  1107.     log_product (args->Hello.product, args->Hello.product_maj, args->Hello.product_min);
  1108.  
  1109.     if (args->Hello.sysop[0])
  1110.         status_line (":Sysop: %s", args->Hello.sysop);
  1111.  
  1112.     if ((pvtnet >= 0) && (remote_addr.Point > 0))
  1113.     {
  1114.         remote_addr.Point = 0;
  1115.         remote_addr.Node = (unsigned short) -1;
  1116.     }
  1117.  
  1118.     if ((j = n_getpassword (&remote_addr)) > 0)
  1119.     {
  1120.         if ((j = n_password ((char *) args->Hello.my_password, remote_password, &logit)) != 0)
  1121.         {
  1122.             if ((j == 1) || ((j == 2) && (args->sender == 0)))
  1123.                 goto blew_it;
  1124.             else
  1125.             {
  1126.                 status_line (MSG_TXT (M_PASSWORD_OVERRIDE));
  1127.             }
  1128.         }
  1129.     }
  1130.     else if (j < 0)
  1131.     {
  1132.         status_line (MSG_TXT (M_NUISANCE_CALLER));
  1133.  
  1134. blew_it:
  1135.  
  1136.         LOWER_DTR ();            /* He'll never get it right */
  1137.         timer (2);                /* Wait two secs */
  1138.         return (RHexit);
  1139.     }
  1140.  
  1141.     CLEAR_INBOUND ();
  1142.     SENDBYTE (ACK);
  1143.  
  1144.     args->result = 1;
  1145.     return (RHexit);
  1146. }
  1147.